package cn.iocoder.yudao.module.shop.info.controller.app;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.business.basic.pojo.vo.ShopSimpleVO;
import cn.iocoder.yudao.framework.business.basic.pojo.vo.UserSimpleVO;
import cn.iocoder.yudao.framework.business.eligibility.pojo.vo.EligibilityApplyCheckVO;
import cn.iocoder.yudao.framework.business.evaluation.enums.ScoreLevelEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.api.member.user.MemberUserApi;
import cn.iocoder.yudao.module.api.product.evaluation.ProductEvaluationApi;
import cn.iocoder.yudao.module.api.promotion.coupon.CouponRecordApi;
import cn.iocoder.yudao.module.api.promotion.coupon.CouponTemplateApi;
import cn.iocoder.yudao.module.api.promotion.coupon.dto.CouponTemplateRespDTO;
import cn.iocoder.yudao.module.api.promotion.groupon.GrouponPackageApi;
import cn.iocoder.yudao.module.api.promotion.groupon.dto.GrouponPackageRespDTO;
import cn.iocoder.yudao.module.api.shop.category.eums.ShopCategoryCodeEnum;
import cn.iocoder.yudao.module.api.shop.info.enums.ShopOwnerTypeEnum;
import cn.iocoder.yudao.module.shop.category.pojo.po.ShopCategory;
import cn.iocoder.yudao.module.shop.category.pojo.vo.AppShopCategoryRespVO;
import cn.iocoder.yudao.module.shop.category.service.ShopCategoryService;
import cn.iocoder.yudao.module.shop.favorite.service.AppShopFavoriteService;
import cn.iocoder.yudao.module.shop.info.dal.dataobject.ShopInfoDO;
import cn.iocoder.yudao.module.shop.info.service.ShopInfoService;
import cn.iocoder.yudao.module.shop.info.vo.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import jakarta.validation.Valid;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType;

@Tag(name = "用户 App - 店铺信息")
@RestController
@RequestMapping("/shop/info")
@Validated
public class AppShopInfoController {

    @Resource
    private ShopInfoService shopInfoService;
    @Resource
    private ShopCategoryService shopCategoryService;
    @Resource
    private AppShopFavoriteService shopFavoriteService;

    @Resource
    private CouponTemplateApi couponTemplateApi;
    @Resource
    private CouponRecordApi couponRecordApi;
    @Resource
    private ProductEvaluationApi productEvaluationApi;
    @Resource
    private GrouponPackageApi grouponPackageApi;
    @Resource
    private MemberUserApi memberUserApi;

    @GetMapping("/get-category-list")
    @Operation(summary = "获得主营类目", description = "用于主营类目选择，如平台商城的产品分类、O2O商圈的商家分类")
    @Parameter(name = "type", deprecated = true, description = "商家类型：0-零售商（线下实体门店+线上商城店铺）、1-批发商（线上投资货物）、2-供货商（线上供应货物）。使用`/shop/category/list`代替", example = "0")
    @PermitAll
    public CommonResult<List<AppShopCategoryRespVO>> getShopCategoryList(@RequestParam(value = "type", required = false) Integer type) {
        // 新版本废弃，但是需要兼容旧版本客户端
        if (Objects.equals(ShopOwnerTypeEnum.WHOLESALER.getValue(), type) ||
            Objects.equals(ShopOwnerTypeEnum.MANUFACTURER.getValue(), type)) {
            // 批发商及供货商的主营类目只能是普通商品
            List<ShopCategory> list = shopCategoryService.getEnableCategoryList(ShopCategoryCodeEnum.MALL.getCode());
            return success(BeanUtils.toBean(list, AppShopCategoryRespVO.class));
        }
        List<ShopCategory> list = shopCategoryService.getEnableRootCategoryList();
        return success(BeanUtils.toBean(list, AppShopCategoryRespVO.class));
    }

    @GetMapping("/check")
    @Operation(summary = "检查我的入驻情况")
    public CommonResult<EligibilityApplyCheckVO<AppMyShopInfoVO>> check() {
        EligibilityApplyCheckVO<AdminShopInfoVO> respVO = shopInfoService.check(getLoginUserId(), getLoginUserType());
        EligibilityApplyCheckVO<AppMyShopInfoVO> result = new EligibilityApplyCheckVO<>();
        result.setInfo(respVO.getInfo());
        result.setStep(respVO.getStep());
        result.setTips(respVO.getTips());
        return success(result);
    }

    @PostMapping("/save")
    @Operation(summary = "创建或更新信息", description = "用于初次申请提交资料或审核不通过的情况重新提交资料。此处只是线下实体店家申请入驻，线上零售商家及货源厂家不在此处入驻")
    public CommonResult<Long> apply(@Valid @RequestBody AppShopInfoSaveDTO reqVO) {
        Long id = shopInfoService.apply(getLoginUserId(), getLoginUserType(), reqVO);
        return success(id);
    }

    @PostMapping("/update-basic")
    @Operation(summary = "更新基础信息")
    public CommonResult<Boolean> updateShopBasic(@Valid @RequestBody ShopInfoBasicUpdateReqVO updateReqVO) {
        shopInfoService.updateInfo(getLoginUserId(), getLoginUserType(), updateReqVO);
        return success(true);
    }

    @PostMapping("/update-address")
    @Operation(summary = "更新经营地址")
    public CommonResult<Boolean> updateShopAddress(@Valid @RequestBody ShopAddressSaveForm updateReqVO) {
        shopInfoService.updateAddress(getLoginUserId(), getLoginUserType(), updateReqVO);
        return success(true);
    }

    @PostMapping("/update-category")
    @Operation(summary = "更新主营类目")
    public CommonResult<Boolean> updateShopCategory(@Valid @RequestBody ShopCategoryUpdateReqVO updateReqVO) {
        shopInfoService.updateCategory(getLoginUserId(), getLoginUserType(), updateReqVO);
        return success(true);
    }

    @PostMapping("/update-status")
    @Operation(summary = "更新经营状态")
    public CommonResult<Boolean> updateShopStatus(@Valid @RequestBody ShopStatusUpdateReqVO updateReqVO) {
        shopInfoService.updateStatus(getLoginUserId(), getLoginUserType(), updateReqVO);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得店铺信息", description = "用于展示店铺的公开信息")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PermitAll
    public CommonResult<AppShopInfoVO> getShopInfo(@RequestParam("id") Long id) {
        ShopInfoDO shopInfoDO = shopInfoService.getInfo(id);
        AppShopInfoVO data = BeanUtils.toBean(shopInfoDO, AppShopInfoVO.class);
        if (shopInfoDO == null) {
            return success(null);
        }
        // 处理主营类目
        ShopCategory categoryDO = shopCategoryService.getCategory(data.getCategoryId());
        if (categoryDO != null) {
            data.setCategoryName(categoryDO.getName());
            data.setCategoryCode(categoryDO.getCode());
        }
        // 处理优惠券
        List<CouponTemplateRespDTO> coupons = couponTemplateApi.getCanTakeCouponTemplateListByShopId(data.getId());
        Set<Long> templateIds = coupons.stream().map(CouponTemplateRespDTO::getId).collect(Collectors.toSet());
        Map<Long, Boolean> couponReceivedStateMap = couponRecordApi.getCouponReceivedStateMap(getLoginUserId(), templateIds);
        coupons.forEach(item -> item.setIsReceive(Boolean.TRUE.equals(couponReceivedStateMap.get(item.getId()))));
        data.setCoupons(coupons);
        // 处理评价
        data.setScore(productEvaluationApi.calculateScoreByShopId(data.getId()));
        data.setScoreLevel(ScoreLevelEnum.fromScore(data.getScore()).getValue());
        data.setCommentCount(productEvaluationApi.getCommentCount(data.getId()));
        // 处理收藏
        data.setFollow(shopFavoriteService.isTrue(id, getLoginUserId()));
        // 处理团购套餐
        Map<Long, List<GrouponPackageRespDTO>> grouponPackageMap = grouponPackageApi.getMapByShopIds(Collections.singleton(data.getId()));
        List<GrouponPackageRespDTO> grouponPackages = grouponPackageMap.getOrDefault(data.getId(), null);
        data.setGrouponPackages(grouponPackages);
        // 处理销量
        data.setSalesCount(0);
        data.setSalesCountPerMonth(0);
        data.setDeliveryMinPrice(0);
        data.setAvgConsumePrice(0);
        // 商家邀请码
        UserSimpleVO user = memberUserApi.getUser(data.getUserId());
        if (user != null) {
            data.setInviteCode(user.getNo());
        }
        return success(data);
    }


    @GetMapping("/get-simple")
    @Operation(summary = "获得店铺简单信息")
    @Parameter(name = "shopId", description = "店铺编号", required = true, example = "1024")
    @PermitAll
    public CommonResult<ShopSimpleVO> getUserSimple(@RequestParam("shopId") Long shopId) {
        ShopInfoDO shopInfoDO = shopInfoService.getInfo(shopId);
        if (shopInfoDO == null) {
            return success(null);
        }
        return success(BeanUtils.toBean(shopInfoDO, ShopSimpleVO.class));
    }

    @GetMapping("/my")
    @Operation(summary = "获得我的店铺信息", description = "包含非公开的店铺信息，如：负责人身份证信息")
    public CommonResult<AppMyShopInfoVO> getMyShopInfo() {
        EligibilityApplyCheckVO<AdminShopInfoVO> respVO = shopInfoService.check(getLoginUserId(), getLoginUserType());
        return success(respVO.getInfo());
    }

    @GetMapping("/page")
    @Operation(summary = "获得店铺信息分页")
    @Parameter(name = "pageNo", description = "页码", required = true, example = "1")
    @Parameter(name = "pageSize", description = "每页数据条数", required = true, example = "10")
    @PermitAll
    public CommonResult<PageResult<AppShopInfoVO>> getShopInfoPage(@RequestParam("pageNo") Integer current, @RequestParam("pageSize") Integer size, @Valid AppShopInfoQueryDTO pageReqVO) {
        PageResult<ShopInfoDO> pageResult = shopInfoService.getInfoPage(current, size, pageReqVO);
        PageResult<AppShopInfoVO> data = BeanUtils.toBean(pageResult, AppShopInfoVO.class);
        return success(toCommonResult(data));
    }

    private PageResult<AppShopInfoVO> toCommonResult(PageResult<AppShopInfoVO> pageResult) {
        Set<Long> categoryIds = pageResult.getList().stream().map(AppShopInfoVO::getCategoryId).collect(Collectors.toSet());
        Map<Long, ShopCategory> categoryMap = shopCategoryService.getCategoryMap(categoryIds);
        Set<Long> shopIds = pageResult.getList().stream().map(AppShopInfoVO::getId).collect(Collectors.toSet());
        Map<Long, List<CouponTemplateRespDTO>> couponMap = couponTemplateApi.getCanTakeCouponTemplateMap(shopIds);
        Set<Long> templateIds = new HashSet<>();
        couponMap.values().forEach(it -> templateIds.addAll(it.stream().map(CouponTemplateRespDTO::getId).collect(Collectors.toSet())));
        Map<Long, Boolean> couponReceivedStateMap = couponRecordApi.getCouponReceivedStateMap(getLoginUserId(), templateIds);
        Map<Long, Boolean> favorites = shopFavoriteService.getStateMap(shopIds, getLoginUserId());
        Map<Long, List<GrouponPackageRespDTO>> grouponPackageMap = grouponPackageApi.getMapByShopIds(shopIds);
        pageResult.getList().forEach(it -> {
            // 处理主营类目
            ShopCategory categoryDO = categoryMap.get(it.getCategoryId());
            if (categoryDO != null) {
                it.setCategoryName(categoryDO.getName());
                it.setCategoryCode(categoryDO.getCode());
            }
            // 处理优惠券
            List<CouponTemplateRespDTO> coupons = couponMap.get(it.getId());
            if (CollUtil.isNotEmpty(coupons)) {
                coupons.forEach(item -> item.setIsReceive(Boolean.TRUE.equals(couponReceivedStateMap.get(item.getId()))));
            } else {
                coupons = new ArrayList<>();
            }
            it.setCoupons(coupons);
            // 处理团购套餐
            it.setGrouponPackages(grouponPackageMap.get(it.getId()));
            // 处理收藏
            it.setFollow(favorites.getOrDefault(it.getId(), false));
            // 处理销量 TODO 待计算
            it.setSalesCount(0);
            it.setSalesCountPerMonth(0);
            it.setDeliveryMinPrice(0);
            it.setAvgConsumePrice(0);
        });
        return pageResult;
    }

}
